package com.spark.gaea.data.mybatis;

import com.spark.gaea.data.utils.Param;
import com.spark.gaea.utils.CodeUtil;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.io.Serializable;
import java.util.List;
import java.util.Map;

@Service
@Transactional
public class TreeService {
	public static final String CLASSNAME = TreeService.class.getName() + '.';
	@Autowired
	private Dao dao;

	public void updateLeaf(String tableName) {
		Map<String, Object> params = Param.get().put("tableName", tableName).build();


		this.dao.update(CLASSNAME, "updateLeaf", params);
		this.dao.update(CLASSNAME, "updateNotLeaf", params);
	}

	public String getLastCodeByParent(String tableName, Serializable parentId) {
		Map<String, Object> params = Param.get().put("tableName", tableName).put("parentId", parentId).build();


		return (String) this.dao.get(CLASSNAME, "getLastCodeByParent", params);
	}

	public void updateCode(String tableName, Serializable id, String code) {
		Map<String, Object> params = Param.get().put("tableName", tableName).put("id", id).put("code", code).build();
		this.dao.update(CLASSNAME, "updateCode", params);
	}

	public String generateCode(String tableName, Serializable parentId) {
		String lastCode = getLastCodeByParent(tableName, parentId);
		String nextCode;
		if (StringUtils.isNotBlank(lastCode)) {
			nextCode = CodeUtil.getNextCode(lastCode);
		} else {
			String parentCode = getCodeById(tableName, parentId);
			if (parentCode != null) {
				nextCode = CodeUtil.getFirstCode(parentCode);
			} else {
				nextCode = CodeUtil.getFirstCode(null);
			}
		}
		return nextCode;
	}

	public String getCodeById(String tableName, Serializable id) {
		Map<String, Object> params = Param.get().put("tableName", tableName).put("id", id).build();


		return (String) this.dao.get(CLASSNAME, "getCodeById", params);
	}

	public List<Map<String, Serializable>> likeByCode(String tableName, String code) {
		Map<String, Object> params = Param.get().put("tableName", tableName).putLikeR("code", code).build();


		return this.dao.getList(CLASSNAME, "likeByCode", params);
	}

	public void updateParentIdCode(String tableName, Serializable id, Serializable parentId, String code) {
		Map<String, Object> params = Param.get().put("tableName", tableName).put("id", id).put("parentId", parentId)
				.put("code", code).build();


		this.dao.update(CLASSNAME, "updateParentIdCode", params);
	}

	public void resetCode(String tableName, Serializable id, Serializable oldParentId, Serializable newParentId) {

		if (!oldParentId.equals(newParentId)) {
			String oldCode = getCodeById(tableName, id);

			String code = generateCode(tableName, newParentId);

			updateParentIdCode(tableName, id, newParentId, code);


			List<Map<String, Serializable>> childs = likeByCode(tableName, oldCode);
			for (Map<String, Serializable> child : childs) {
				String childNewCode = ((String) child.get("code")).replace(oldCode, code);
				updateCode(tableName, child.get("id"), childNewCode);
			}
		}
	}
}
